package org.alvin.code.tools;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;


public class AESUtils {

    private static final String ENCODING = "utf-8";

    private static final String AES = "AES";

    /**
     * base64加密
     *
     * @param input
     * @return
     * @throws Exception
     */
    public static String encodeBase64(byte[] input) throws Exception {
        return new String(Base64.getEncoder().encode(input), ENCODING);
    }

    /*** 
     * decode by Base64 
     */
    public static byte[] decodeBase64(String input) throws Exception {
        return Base64.getDecoder().decode(input);
    }

    /**
     * 获取密钥
     *
     * @param password 加密密码
     * @return
     * @throws NoSuchAlgorithmException
     */
    private static SecretKeySpec getKey(String password)
            throws NoSuchAlgorithmException {
        // 密钥加密器生成器
        KeyGenerator kgen = KeyGenerator.getInstance(AES);
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");// 需要自己手动设置
        random.setSeed(password.getBytes());
        kgen.init(128, random);
        // 创建加密器
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES);
        return key;
    }

    /**
     * aes 加密并返回Base64
     * @param data
     * @param password
     * @return
     * @throws Exception
     */
    public static String aesEncode2Base64(String data,
                                          String password) throws Exception {
        Cipher cipher = Cipher.getInstance(AES);
        byte[] byteContent = data.getBytes(ENCODING);
        cipher.init(Cipher.ENCRYPT_MODE, getKey(password));
        byte[] result = cipher.doFinal(byteContent);
        return encodeBase64(result);
    }

    /**
     * 解密并返回base64
     * @param data
     * @param password
     * @return
     * @throws Exception
     */
    public static String aesDecode2ByBase64(String data,
                                            String password) throws Exception {
        byte[] content = decodeBase64(data);
        byte[] result = null;
        Cipher cipher = Cipher.getInstance(AES);
        cipher.init(Cipher.DECRYPT_MODE, getKey(password));
        result = cipher.doFinal(content);
        return new String(result, ENCODING);
    }


//    public static void main(String[] args) {
//        String msg = "o0EeUs3hy107WsO3qYL0hGzM";
//        try {
//            String encode = aesEncode2Base64(msg,"test");
//            System.out.println("加密：" + encode);
//            System.out.println(System.currentTimeMillis());
//            System.out.println("解密：" + aesDecode2ByBase64(encode,"test"));
//            System.out.println(System.currentTimeMillis());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
}
